package fi.foyt.cs.oauth.provider.data;

import org.restlet.ext.oauth.provider.data.AuthenticatedUser;
import org.restlet.ext.oauth.provider.data.ExpireToken;
import org.restlet.ext.oauth.provider.data.Token;
import org.restlet.ext.oauth.provider.data.TokenGenerator;

import fi.foyt.cs.controller.OAuthController;
import fi.foyt.cs.persistence.domainmodel.oauth.AuthenticatedUserCode;
import fi.foyt.cs.persistence.domainmodel.oauth.AuthenticatedUserToken;

public class GAETokenGenerator extends TokenGenerator {

  public GAETokenGenerator() {
    super();
  }

  @Override
  public String generateCode(AuthenticatedUser user) {
    String code = super.generateCode(user);
    
    OAuthController oAuthController = new OAuthController();
    fi.foyt.cs.persistence.domainmodel.oauth.AuthenticatedUser authenticatedUser = oAuthController.findAuthenticatedUserByUserId(user.getId());

    AuthenticatedUserCode authenticatedUserCode = oAuthController.findAuthenticatedUserCodeByAuthenticatedUser(authenticatedUser);
    if (authenticatedUserCode != null) {
      oAuthController.deleteAuthenticatedUserCode(authenticatedUserCode);
    }
    
    oAuthController.createAuthenticatedUserCode(authenticatedUser, code);
    
    return code;
  }

  @Override
  public Token generateToken(AuthenticatedUser user, long expire) {
    Token token = super.generateToken(user, expire);
    
    OAuthController oAuthController = new OAuthController();
    fi.foyt.cs.persistence.domainmodel.oauth.AuthenticatedUser authenticatedUser = oAuthController.findAuthenticatedUserByUserId(user.getId());
    oAuthController.createAuthenticatedUserToken(authenticatedUser, token.getToken());

    return token;
  }

  @Override
  public Token exchangeForToken(String code, long expire) throws IllegalArgumentException {
    OAuthController oAuthController = new OAuthController();
    AuthenticatedUserCode authenticatedUserCode = oAuthController.findAuthenticatedUserCodeByCode(code);
    if (authenticatedUserCode == null)
      throw new IllegalArgumentException("Code not valid");

    fi.foyt.cs.persistence.domainmodel.oauth.AuthenticatedUser authenticatedUser = oAuthController.findAuthenticatedUserById(authenticatedUserCode.getAuthenticatedUserId());
    GAEAuthenticatedUser gaeAuthenticatedUser = new GAEAuthenticatedUser(authenticatedUser.getUserId());
    gaeAuthenticatedUser.removeCode(code);
    
    return generateToken(gaeAuthenticatedUser, expire);
  }

  @Override
  public void revokeToken(Token token) {
    OAuthController oAuthController = new OAuthController();
    AuthenticatedUserToken authenticatedUserToken = oAuthController.findAuthenticatedUserTokenByToken(token.getToken());
    if (authenticatedUserToken != null) {
      oAuthController.deleteAuthenticatedUserToken(authenticatedUserToken);
    }
  }

  @Override
  public void revokeExpireToken(ExpireToken token) {
    OAuthController oAuthController = new OAuthController();
    AuthenticatedUserToken authenticatedUserToken = oAuthController.findAuthenticatedUserTokenByToken(token.getToken());
    if (authenticatedUserToken != null) {
      oAuthController.deleteAuthenticatedUserToken(authenticatedUserToken);
    }
  }

  @Override
  public Token findToken(String token) {
    OAuthController oAuthController = new OAuthController();
    AuthenticatedUserToken authenticatedUserToken = oAuthController.findAuthenticatedUserTokenByToken(token);
    fi.foyt.cs.persistence.domainmodel.oauth.AuthenticatedUser authenticatedUser = oAuthController.findAuthenticatedUserById(authenticatedUserToken.getAuthenticatedUserId());
    GAEAuthenticatedUser gaeAuthenticatedUser = new GAEAuthenticatedUser(authenticatedUser.getUserId());
    return new Token(authenticatedUserToken.getToken(), gaeAuthenticatedUser) {};
  }

  @Override
  public void refreshToken(ExpireToken token) {
    super.refreshToken(token);
  }
}